package me.zhengjie.tool;

import com.google.common.collect.Lists;
import me.zhengjie.vo.MinAndMaxVO;
import me.zhengjie.vo.StandardVO;
import me.zhengjie.vo.SumVO;

import java.io.Serializable;
import java.lang.reflect.Method;
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

import static java.util.Comparator.comparing;
public class ListUtil implements Serializable {
    private static final long serialVersionUID = 3049484267650886092L;

    /**
     * 将List<Map>转换为List<MyMap>
     *
     * @param list
     * @return
     */
    public static List<MyMap> mapList2MyMapList(List<Map> list) {
        return list.stream().map(map -> new MyMap(map)).collect(Collectors.toList());
    }

    /**
     * 将List转换成JSON字符串
     *
     * @param list
     * @param id
     * @param name
     * @return
     */
    @SuppressWarnings("rawtypes")
    public static String getSelectJSON(List<Map> list, String id, String name) {
        int listsize = list.size();
        if (listsize == 0) {
            return "[]";
        }
        StringBuffer sb = new StringBuffer("");
        list.stream().forEach(map -> sb.append("{'id':'").append(map.get(id)).append("',").append("'name':'")
                .append(map.get(name)).append("'},"));
        String str = null;
        if (listsize > 0) {
            str = "[" + sb.substring(0, sb.lastIndexOf(",")) + "]";
        }
        return str;
    }

    /**
     * list 转为下拉框用的list
     *
     * @param list
     * @param id
     * @param name
     * @return
     */
    @SuppressWarnings({"rawtypes", "unchecked"})
    public static List<MyMap> getSelectList(List<Map> list, String id, String name) {
        return list.stream().map(map -> new MyMap().putValue("id", map.get(id)).putValue("name", map.get(name))).collect(Collectors.toList());
    }

    /**
     * 期号分段
     *
     * @param list 期号List<String>
     * @param mode 分段类型
     *             "normal":连续分段 "year":自然年度分段
     * @return 时间段List
     * @throws Exception
     */
    @SuppressWarnings({"rawtypes", "unchecked"})
    public static List<Map> getSubsection(List<String> list, String mode) {
        List<Map> resultlist = new ArrayList<>();
        Collections.sort(list);// 排序
        Ym nowDate;// 当前期次转换为时间
        Ym nextDate;// 下一个月的时间
        //Calendar c1 = Calendar.getInstance();
        //SimpleDateFormat sdf = new SimpleDateFormat(Constant.DEFAULT_FORMAT_YM);// 定义时间转换格式
        //Date nowDate;// 当前期次转换为时间
        //String nextDate;// 下一个月的时间
        Map map = new HashMap();// 返回时间段信息
        if (list.size() == 1) {// 如果只有一条时间记录，则这条记录既是开始时间又是结束时间
            return list.stream().map(s -> new MyMap().putValue("star", s).putValue("end", s)).collect(Collectors.toList());
        }
        if ("normal".endsWith(mode)) {// 表示按正常时间段划分
            for (int i = 0, len = list.size(); i < len; i++) {
                if (i == 0) {
                    map = new HashMap();
                    map.put("star", list.get(i));// 第一条信息为开始时间
                } else if (i == len - 1) {// 当当前期次为最后一个
                    map.put("end", list.get(i));
                    resultlist.add(map);
                    continue;
                }
                nowDate = new Ym(list.get(i));
                nextDate = nowDate.addMonths(1);
                if (!nextDate.toString().equals(list.get(i + 1))) {// 如果当前月份的下一个月，与下一个期号不同，则代表其次好已经断开
                    map.put("end", list.get(i));
                    resultlist.add(map);
                    map = new HashMap();
                    map.put("star", list.get(i + 1));
                }
            }
        } else if ("year".equals(mode)) {
            for (int i = 0, len = list.size(); i < len; i++) {
                if (i == 0) {
                    map = new HashMap();
                    map.put("star", list.get(i));// 第一条信息为开始时间
                } else if (i == len - 1) {// 当当前期次为最后一个
                    map.put("end", list.get(i));
                    resultlist.add(map);
                    continue;
                }
                nowDate = new Ym(list.get(i));
                nextDate = nowDate.addMonths(1);
                if (!nextDate.toString().equals(list.get(i + 1))) {// 如果当前月份的下一个月，与下一个期号不同，则代表其次好已经断开
                    map.put("end", list.get(i));
                    resultlist.add(map);
                    map = new HashMap();
                    map.put("star", list.get(i + 1));
                    continue;
                }
                if ("12".equals(list.get(i).substring(4, 6))) {
                    map.put("end", list.get(i));
                    resultlist.add(map);
                    map = new HashMap();
                    map.put("star", list.get(i + 1));
                }
            }
        } else {
            throw new IllegalArgumentException("传入的分段方式错误");
        }

        return resultlist;
    }

    /**
     * List分组
     *
     * @param list   基础List
     * @param mode   分组规则
     *               "aae140,aaa115"
     * @param column 被分组字段
     *               "aae003"
     * @return 分组结果 "11010,{201506,201507,201508...}"
     * @throws Exception
     */
    @SuppressWarnings({"rawtypes", "unchecked"})
    public static Map<String, List> getGroup(List<Map> list, String mode, String column) {
        if (ValidateUtil.isEmpty(mode)) {
            throw new IllegalArgumentException("分组失败，请传入分组规则！");
        }
        if (ValidateUtil.isEmpty(list)) {
            throw new IllegalArgumentException("分组失败，请传入分组数据！");
        }
        if (ValidateUtil.isEmpty(column)) {
            throw new IllegalArgumentException("分组失败，请传入被分组字段！");
        }
        List<String> modeLists = string2List(mode, ",");
        List<MyMap> modeMapList = new ArrayList();
        //用对应分组规则的值和被分组字段的值组成map放入list
        list.stream().forEach(map -> {
            StringBuilder stringBuilder = new StringBuilder("");
            modeLists.stream().forEach(s -> stringBuilder.append(map.get(s)));
            modeMapList.add(new MyMap().putValue(stringBuilder.toString(), map.get(column).toString()));
        });
        Set<String> resultSet = new HashSet();
        modeMapList.stream().forEach(myMap -> {
            Set<Map.Entry<String, String>> set = myMap.entrySet();
            set.stream().forEach(entry -> resultSet.add(entry.getKey()));
        });
        Map<String, List> resultMap = new HashMap();
        resultSet.stream().forEach(str -> {
            List<String> resultList = new ArrayList();
            modeMapList.stream().forEach(myMap -> {
                if (myMap.get(str) != null) {
                    resultList.add(myMap.getAsString(str));
                }
            });
            resultMap.put(str, resultList);
        });

        /*String[] modes = mode.split(",");// 分割分组规则
        String key = "";
        Map<String, String> modeMap;
        List<Map<String, String>> modeList = new ArrayList<Map<String, String>>();// 构建分组规则List

        for (Map map : list) {
            key = "";
            for (int i = 0; i < modes.length; i++) {
                key += map.get(modes[i]);
            }
            modeMap = new HashMap();
            modeMap.put(key, map.get(column).toString());
            modeList.add(modeMap);
        }

        Set<String> resultSet = new HashSet();
        Set<Map.Entry<String, String>> set;
        for (Map m : modeList) {
            set = m.entrySet();
            for (Map.Entry<String, String> entry : set) {
                resultSet.add(entry.getKey());
            }
        }
        Map<String, List<String>> resultMap = new HashMap();
        List<String> resultList;
        for (String s : resultSet) {
            resultList = new ArrayList();
            for (Map m : modeList) {
                if (m.get(s) != null) {
                    resultList.add(m.get(s).toString());
                }
            }
            resultMap.put(s, resultList);
        }*/
        return resultMap;
    }

    /**
     * 根据一定的规则，进行分组
     *
     * @param list 划分入参
     * @param mode 划分方式：为Map的key值，用逗号隔开，前面为划分依据，最后一个为划分对象
     *             如：mode="aae140,aaa115,aae003" 表示根据险种类型与应缴类型，划分费款所属期
     * @return 就是划分方式，与分组列表
     * 如："11010,{201506,201507,201508...}"
     * @throws Exception
     */
    public static Map<String, List> getGroup(List<Map> list, String mode) {
        if (ValidateUtil.isEmpty(mode)) {
            throw new IllegalArgumentException("分组失败，请传入划分方式！");
        }
        if (ValidateUtil.isEmpty(list)) {
            throw new IllegalArgumentException("分组失败，请传入分组数据！");
        }
        List<String> modeLists = string2List(mode, ",");
        String column = modeLists.get(modeLists.size() - 1);
        modeLists.remove(column);
        mode = modeLists.stream().collect(Collectors.joining(","));
        return getGroup(list, mode, column);
    }

    /**
     * 根据一定的规则，进行分组
     *
     * @param list 划分入参
     * @param mode 划分方式：为Map的key值，用逗号隔开，作为为划分依据
     * @return
     * @throws Exception
     */
    public static Map<String, List<Map>> getGroup_2(List<Map> list, String mode) {
        if (ValidateUtil.isEmpty(mode)) {
            throw new IllegalArgumentException("分组失败，请传入分组依据！");
        }
        if (ValidateUtil.isEmpty(list)) {
            throw new IllegalArgumentException("分组失败，请传入分组数据！");
        }
        Map<String, List<Map>> map = new HashMap<>();
        List<String> list_mode = string2List(mode, ",");
        //数据分组
        list.stream().forEach(map1 -> {
            StringBuilder stringBuilder = new StringBuilder("");
            list_mode.stream().forEach(s -> stringBuilder.append(map1.get(s)));
            List<Map> list_group = ValidateUtil.isEmpty(map.get(stringBuilder.toString())) ? new ArrayList() : map.get(stringBuilder.toString());
            list_group.add(map1);
            map.put(stringBuilder.toString(), list_group);
        });
        return map;
    }

    /**
     * 根据一定的规则，进行分组(单一参数规则)
     *
     * @param list 划分入参
     * @param mode 划分方式：为Map的key值，key值为单一值
     * @return
     * @throws Exception
     */
    public static Map<String, List<Map>> getGroup_3(List<Map> list, String mode) {
        if (ValidateUtil.isEmpty(mode)) {
            throw new IllegalArgumentException("分组失败，请传入分组依据！");
        }
        if (ValidateUtil.isEmpty(list)) {
            throw new IllegalArgumentException("分组失败，请传入分组数据！");
        }
        Map<String, List<Map>> map = new HashMap<>();
        //循环分组数据
        list.stream().forEach(map1 -> {
            String key = ValidateUtil.isEmpty(map1.get(mode)) ? "" : map1.get(mode).toString();
            List<Map> list_group = ValidateUtil.isEmpty(map.get(key)) ? new ArrayList() : map.get(key);
            list_group.add(map1);
            map.put(key, list_group);
        });
        return map;
    }

    /**
     * List求最小值和最大值
     *
     * @param list        基础List
     * @param minAndMaxVO 第一组求和
     * @throws Exception
     */
    @SuppressWarnings("rawtypes")
    public static void getMinAndMax(List list, MinAndMaxVO minAndMaxVO) {
        if (ValidateUtil.isEmpty(list)) {
            if ("String".equals(minAndMaxVO.getType())) {
                minAndMaxVO.setMinValue(null);
                minAndMaxVO.setMaxValue(null);
            } else if ("Integer".equals(minAndMaxVO.getType())) {
                minAndMaxVO.setMinValue("0");
                minAndMaxVO.setMaxValue("0");
            } else if ("BigDecimal".equals(minAndMaxVO.getType())) {
                minAndMaxVO.setMinValue("0.00");
                minAndMaxVO.setMaxValue("0.00");
            } else {
                minAndMaxVO.setMinValue(null);
                minAndMaxVO.setMaxValue(null);
            }
        } else {
            StandardVO standardVO = new StandardVO();
            standardVO.setColumn(minAndMaxVO.getColumn());
            standardVO.setType(minAndMaxVO.getType());
            standardVO.setSort("asc");
            list = sorts(list, standardVO);
            String minValue = ((Map) list.get(0)).get(minAndMaxVO.getColumn()).toString();
            String maxValue = ((Map) list.get(list.size() - 1)).get(minAndMaxVO.getColumn()).toString();
            minAndMaxVO.setMinValue(minValue);
            minAndMaxVO.setMaxValue(maxValue);
        }
    }

    /**
     * List求和
     *
     * @param list   基础List
     * @param sumVO1 第一组求和
     * @throws Exception
     */
    @SuppressWarnings("rawtypes")
    public static void getSum(List list, SumVO sumVO1) {
        BigDecimal result_1 = new BigDecimal("0.00");
        Map map;
        for (int i = 0; i < list.size(); i++) {
            map = (Map) list.get(i);
            result_1 = result_1.add(new BigDecimal(map.get(sumVO1.getColumn()).toString()));
        }
        sumVO1.setResult(result_1);
    }

    /**
     * List求和
     *
     * @param list   基础List
     * @param sumVO1 第一组求和
     * @param sumVO2 第二组求和
     * @throws Exception
     */
    @SuppressWarnings("rawtypes")
    public static void getSum(List list, SumVO sumVO1, SumVO sumVO2) {
        getSum(list, sumVO1);
        getSum(list, sumVO2);
    }

    /**
     * List求和
     *
     * @param list   基础List
     * @param sumVO1 第一组求和
     * @param sumVO2 第二组求和
     * @param sumVO3 第三组求和
     * @throws Exception
     */
    @SuppressWarnings("rawtypes")
    public static void getSum(List list, SumVO sumVO1, SumVO sumVO2, SumVO sumVO3) {
        getSum(list, sumVO1);
        getSum(list, sumVO2);
        getSum(list, sumVO3);
    }

    /**
     * List求和
     *
     * @param list   基础List
     * @param sumVO1 第一组求和
     * @param sumVO2 第二组求和
     * @param sumVO3 第三组求和
     * @param sumVO4 第四组求和
     * @throws Exception
     */
    @SuppressWarnings("rawtypes")
    public static void getSum(List list, SumVO sumVO1, SumVO sumVO2, SumVO sumVO3, SumVO sumVO4) {
        getSum(list, sumVO1);
        getSum(list, sumVO2);
        getSum(list, sumVO3);
        getSum(list, sumVO4);
    }

    /**
     * List求和
     *
     * @param list   基础List
     * @param sumVO1 第一组求和
     * @param sumVO2 第二组求和
     * @param sumVO3 第三组求和
     * @param sumVO4 第四组求和
     * @param sumVO5 第五组求和
     * @throws Exception
     */
    @SuppressWarnings("rawtypes")
    public static void getSum(List list, SumVO sumVO1, SumVO sumVO2, SumVO sumVO3, SumVO sumVO4, SumVO sumVO5) {
        getSum(list, sumVO1);
        getSum(list, sumVO2);
        getSum(list, sumVO3);
        getSum(list, sumVO4);
        getSum(list, sumVO5);
    }

    /**
     * List排序
     *
     * @param list        排序List
     * @param standardVO1 第一排序标准
     * @return
     * @throws Exception
     */
    @SuppressWarnings({"rawtypes"})
    public static List sorts(List list, StandardVO standardVO1) {
        List<StandardVO> standardVOList = new ArrayList<>();
        standardVOList.add(standardVO1);
        return sorts(list, standardVOList);
    }

    /**
     * List排序
     *
     * @param list        排序List
     * @param standardVO1 第一排序标准
     * @param standardVO2 第二排序标准
     * @return
     * @throws Exception
     */
    @SuppressWarnings({"rawtypes"})
    public static List sorts(List list, StandardVO standardVO1, StandardVO standardVO2) {
        List<StandardVO> standardVOList = new ArrayList<>();
        standardVOList.add(standardVO1);
        standardVOList.add(standardVO2);
        return sorts(list, standardVOList);
    }

    /**
     * List排序
     *
     * @param list        排序List
     * @param standardVO1 第一排序标准
     * @param standardVO2 第二排序标准
     * @param standardVO3 第三排序标准
     * @return
     * @throws Exception
     */
    @SuppressWarnings({"rawtypes"})
    public static List sorts(List list, StandardVO standardVO1, StandardVO standardVO2, StandardVO standardVO3) {
        List<StandardVO> standardVOList = new ArrayList<>();
        standardVOList.add(standardVO1);
        standardVOList.add(standardVO2);
        standardVOList.add(standardVO3);
        return sorts(list, standardVOList);
    }

    /**
     * List排序
     *
     * @param list        _排序List
     * @param standardVO1 _第一排序标准
     * @param standardVO2 _第二排序标准
     * @param standardVO3 _第三排序标准
     * @param standardVO4 _第四排序标准
     * @return
     * @throws Exception
     */
    @SuppressWarnings({"rawtypes"})
    public static List sorts(List list, StandardVO standardVO1, final StandardVO standardVO2, final StandardVO standardVO3, final StandardVO standardVO4) {
        List<StandardVO> standardVOList = new ArrayList<>();
        standardVOList.add(standardVO1);
        standardVOList.add(standardVO2);
        standardVOList.add(standardVO3);
        standardVOList.add(standardVO4);
        return sorts(list, standardVOList);
    }

    /**
     * List排序
     *
     * @param list        _排序List
     * @param standardVO1 _第一排序标准
     * @param standardVO2 _第二排序标准
     * @param standardVO3 _第三排序标准
     * @param standardVO4 _第四排序标准
     * @param standardVO5 _第五排序标准
     * @return
     * @throws Exception
     */
    @SuppressWarnings({"rawtypes"})
    public static List sorts(List list, StandardVO standardVO1, final StandardVO standardVO2, final StandardVO standardVO3, final StandardVO standardVO4, final StandardVO standardVO5) {
        List<StandardVO> standardVOList = new ArrayList<>();
        standardVOList.add(standardVO1);
        standardVOList.add(standardVO2);
        standardVOList.add(standardVO3);
        standardVOList.add(standardVO4);
        standardVOList.add(standardVO5);
        return sorts(list, standardVOList);
    }

    /**
     * List排序
     *
     * @param list          _排序List
     * @param standardVList _标准集合
     * @return
     * @throws Exception
     */
    @SuppressWarnings({"unchecked", "rawtypes"})
    private static List sorts(List list, final List<StandardVO> standardVList) {
        Collections.sort(list, new Comparator<Map<String, Object>>() {
            public int compare(Map<String, Object> map1, Map<String, Object> map2) {
                if (standardVList.size() == 1) {
                    StandardVO standardVO1 = standardVList.get(0);
                    if (!map1.get(standardVO1.getColumn()).toString().equals(map2.get(standardVO1.getColumn()).toString())) {
                        return ListUtil.compare(map1.get(standardVO1.getColumn()).toString(), map2.get(standardVO1.getColumn()).toString(), standardVO1.getType(), standardVO1.getSort());
                    } else {
                        return 0;
                    }
                } else if (standardVList.size() == 2) {
                    StandardVO standardVO1 = standardVList.get(0);
                    StandardVO standardVO2 = standardVList.get(1);
                    if (!map1.get(standardVO1.getColumn()).toString().equals(map2.get(standardVO1.getColumn()).toString())) {
                        return ListUtil.compare(map1.get(standardVO1.getColumn()).toString(), map2.get(standardVO1.getColumn()).toString(), standardVO1.getType(), standardVO1.getSort());
                    } else if (!map1.get(standardVO2.getColumn()).toString().equals(map2.get(standardVO2.getColumn()).toString())) {
                        return ListUtil.compare(map1.get(standardVO2.getColumn()).toString(), map2.get(standardVO2.getColumn()).toString(), standardVO2.getType(), standardVO2.getSort());
                    } else {
                        return 0;
                    }
                } else if (standardVList.size() == 3) {
                    StandardVO standardVO1 = standardVList.get(0);
                    StandardVO standardVO2 = standardVList.get(1);
                    StandardVO standardVO3 = standardVList.get(2);
                    if (!map1.get(standardVO1.getColumn()).toString().equals(map2.get(standardVO1.getColumn()).toString())) {
                        return ListUtil.compare(map1.get(standardVO1.getColumn()).toString(), map2.get(standardVO1.getColumn()).toString(), standardVO1.getType(), standardVO1.getSort());
                    } else if (!map1.get(standardVO2.getColumn()).toString().equals(map2.get(standardVO2.getColumn()).toString())) {
                        return ListUtil.compare(map1.get(standardVO2.getColumn()).toString(), map2.get(standardVO2.getColumn()).toString(), standardVO2.getType(), standardVO2.getSort());
                    } else if (!map1.get(standardVO3.getColumn()).toString().equals(map2.get(standardVO3.getColumn()).toString())) {
                        return ListUtil.compare(map1.get(standardVO3.getColumn()).toString(), map2.get(standardVO3.getColumn()).toString(), standardVO3.getType(), standardVO3.getSort());
                    } else {
                        return 0;
                    }
                } else if (standardVList.size() == 4) {
                    StandardVO standardVO1 = standardVList.get(0);
                    StandardVO standardVO2 = standardVList.get(1);
                    StandardVO standardVO3 = standardVList.get(2);
                    StandardVO standardVO4 = standardVList.get(3);
                    if (!map1.get(standardVO1.getColumn()).toString().equals(map2.get(standardVO1.getColumn()).toString())) {
                        return ListUtil.compare(map1.get(standardVO1.getColumn()).toString(), map2.get(standardVO1.getColumn()).toString(), standardVO1.getType(), standardVO1.getSort());
                    } else if (!map1.get(standardVO2.getColumn()).toString().equals(map2.get(standardVO2.getColumn()).toString())) {
                        return ListUtil.compare(map1.get(standardVO2.getColumn()).toString(), map2.get(standardVO2.getColumn()).toString(), standardVO2.getType(), standardVO2.getSort());
                    } else if (!map1.get(standardVO3.getColumn()).toString().equals(map2.get(standardVO3.getColumn()).toString())) {
                        return ListUtil.compare(map1.get(standardVO3.getColumn()).toString(), map2.get(standardVO3.getColumn()).toString(), standardVO3.getType(), standardVO3.getSort());
                    } else if (!map1.get(standardVO4.getColumn()).toString().equals(map2.get(standardVO4.getColumn()).toString())) {
                        return ListUtil.compare(map1.get(standardVO4.getColumn()).toString(), map2.get(standardVO4.getColumn()).toString(), standardVO4.getType(), standardVO4.getSort());
                    } else {
                        return 0;
                    }
                } else if (standardVList.size() == 5) {
                    StandardVO standardVO1 = standardVList.get(0);
                    StandardVO standardVO2 = standardVList.get(1);
                    StandardVO standardVO3 = standardVList.get(2);
                    StandardVO standardVO4 = standardVList.get(3);
                    StandardVO standardVO5 = standardVList.get(4);
                    if (!map1.get(standardVO1.getColumn()).toString().equals(map2.get(standardVO1.getColumn()).toString())) {
                        return ListUtil.compare(map1.get(standardVO1.getColumn()).toString(), map2.get(standardVO1.getColumn()).toString(), standardVO1.getType(), standardVO1.getSort());
                    } else if (!map1.get(standardVO2.getColumn()).toString().equals(map2.get(standardVO2.getColumn()).toString())) {
                        return ListUtil.compare(map1.get(standardVO2.getColumn()).toString(), map2.get(standardVO2.getColumn()).toString(), standardVO2.getType(), standardVO2.getSort());
                    } else if (!map1.get(standardVO3.getColumn()).toString().equals(map2.get(standardVO3.getColumn()).toString())) {
                        return ListUtil.compare(map1.get(standardVO3.getColumn()).toString(), map2.get(standardVO3.getColumn()).toString(), standardVO3.getType(), standardVO3.getSort());
                    } else if (!map1.get(standardVO4.getColumn()).toString().equals(map2.get(standardVO4.getColumn()).toString())) {
                        return ListUtil.compare(map1.get(standardVO4.getColumn()).toString(), map2.get(standardVO4.getColumn()).toString(), standardVO4.getType(), standardVO4.getSort());
                    } else if (!map1.get(standardVO5.getColumn()).toString().equals(map2.get(standardVO5.getColumn()).toString())) {
                        return ListUtil.compare(map1.get(standardVO5.getColumn()).toString(), map2.get(standardVO5.getColumn()).toString(), standardVO5.getType(), standardVO5.getSort());
                    } else {
                        return 0;
                    }
                } else {
                    return 0;
                }
            }
        });
        return list;
    }

    private static int compare(String value_1, String value_2, String type, String sort) {
        if ("String".equals(type)) {
            if ("desc".equals(sort)) {
                return (value_2).compareTo(value_1);
            } else {
                return (value_1).compareTo(value_2);
            }
        } else if ("Integer".equals(type)) {
            if ("desc".equals(sort)) {
                return new Integer(value_2).intValue() - new Integer(value_1).intValue();
            } else {
                return new Integer(value_1).intValue() - new Integer(value_2).intValue();
            }
        } else if ("BigDecimal".equals(type)) {
            if ("desc".equals(sort)) {
                return (new BigDecimal(value_2)).compareTo(new BigDecimal(value_1));
            } else {
                return (new BigDecimal(value_1)).compareTo(new BigDecimal(value_2));
            }
        } else {
            return 0;
        }
    }

    /**
     * 对List<String>进行排序
     *
     * @param list
     */
    public static void sorts(List<String> list) {
        Collections.sort(list, new Comparator() {
            @Override
            public int compare(Object o1, Object o2) {
                String str1 = (String) o1;
                String str2 = (String) o2;
                if (str1.compareToIgnoreCase(str2) < 0) {
                    return -1;
                }
                return 1;
            }
        });
    }

    /**
     * 分组合并期号
     *
     * @param list_success 需要合并的list
     * @param fzfs         分组字段
     * @return
     */
    public static List<Map> getStartAndEndtime(List<Map> list_success, String fzfs) {
        List<Map> list_result = new ArrayList<>();
        // 按基数信息进行分组，基数相同的信息放到一个list里面
        Map<String, List<Map>> map_group;
        if (!ValidateUtil.isEmpty(fzfs)) {
            map_group = getGroup_2(list_success, fzfs);
        } else {
            map_group = new HashMap<>();
            map_group.put("1", list_success);
        }
        // 对基数相同的信息进行时间段合并
        List<Map> list_group;
        StandardVO standardVO1 = new StandardVO();
        standardVO1.setColumn("aae003");
        standardVO1.setSort("esc");
        standardVO1.setType("Integer");
        for (Map.Entry<String, List<Map>> entry : map_group.entrySet()) {
            list_group = entry.getValue();
            // 对list进行排序
            ListUtil.sorts(list_group, standardVO1);
            if (ValidateUtil.isEmpty(list_group)) {
                continue;
            } else if (list_group.size() == 1) {
                list_group.get(0).put("aae041", list_group.get(0).get("aae003"));
                list_group.get(0).put("aae042", list_group.get(0).get("aae003"));
                list_result.add(list_group.get(0));
            } else {
                Integer aae003 = (Integer) list_group.get(0).get("aae003");
                Map map_part = new HashMap();
                map_part.putAll(list_group.get(0));
                map_part.put("aae041", aae003);
                map_part.put("aae042", aae003);
                map_part.put("addMonth", Ym.addMonths(aae003, 1));
                int length = list_group.size();
                for (int i = 1; i < length; i++) {
                    aae003 = (Integer) list_group.get(i).get("aae003");
                    if (i == length - 1) {
                        if (!aae003.equals(map_part.get("addMonth"))) {
                            // 排除跨时间段
                            list_result.add(map_part);
                            map_part = new HashMap();
                            map_part.putAll(list_group.get(i));
                            map_part.put("aae041", aae003);
                            map_part.put("aae042", aae003);
                            list_result.add(map_part);
                            map_part.put("addMonth", Ym.addMonths(aae003, 1));
                            continue;
                        } else {
                            map_part.put("aae042", aae003);
                            list_result.add(map_part);
                            continue;
                        }
                    }
                    if (!aae003.equals(map_part.get("addMonth"))) {
                        // 排除跨时间段
                        list_result.add(map_part);
                        map_part = new HashMap();
                        map_part.putAll(list_group.get(i));
                        map_part.put("aae041", aae003);
                        map_part.put("aae042", aae003);
                        map_part.put("addMonth", Ym.addMonths(aae003, 1));
                        continue;
                    }
                    map_part.put("aae042", aae003);
                    map_part.put("addMonth", Ym.addMonths(aae003, 1));
                }
            }
        }

        return list_result;
    }

    /**
     * @param voList    实体集合
     * @param sortField 排序字段 eg:aab001
     * @param sortMode  排序规则 true-正序，false-倒序
     * @return void
     * @Author yinyb(rtx)
     * @Descripton
     * @Date 21:37 2019/6/24
     */
    public static <T> void sorts(List<T> voList, String sortField, final boolean sortMode) {
        Collections.sort(voList, new Comparator<T>() {
            @Override
            public int compare(T obj1, T obj2) {
                int retVal = 0;
                try {
                    // 获取getXxx()方法名称
                    String methodStr = "get" + sortField.substring(0, 1).toUpperCase() + sortField.substring(1);
                    Method method1 = obj1.getClass().getMethod(methodStr, null);
                    Method method2 = obj2.getClass().getMethod(methodStr, null);
                    if (sortMode) {
                        retVal = method1.invoke(obj1, null).toString().compareTo(method2.invoke(obj2, null).toString());
                    } else {
                        retVal = method2.invoke(obj2, null).toString().compareTo(method1.invoke(obj1, null).toString());
                    }
                } catch (Exception e) {
                    throw new IllegalArgumentException("List<" + obj1.getClass().getName() + ">排序异常！" + e.getMessage());
                }
                return retVal;
            }
        });
    }

    /**
     * 从List<Map>转换衡List<MyMap>
     *
     * @param mapList
     * @return
     * @throws Exception
     * @author tianqi
     * @datetime 2016年8月19日 上午10:05:11
     * @version 1.0
     * @see
     */
    @SuppressWarnings("rawtypes")
    public static List<MyMap> list2MyMapList(List mapList) {
        List<MyMap> list = new ArrayList();
        MyMap k;
        Map m;
        Object o;
        for (int i = 0; i < mapList.size(); i++) {
            try {
                m = (Map) mapList.get(i);
            } catch (Exception e) {
                o = mapList.get(i);
                m = MapUtil.toMap(o);
            }
            k = new MyMap(m);
            list.add(k);
        }
        return list;
    }

    /**
     * 把拥有统一分隔符的字符串，转换成列表
     *
     * @param s         需要装换的字符串
     * @param separator 分隔符
     * @return
     * @throws Exception
     * @author tianqi
     * @datetime 2016年8月19日 下午5:20:11
     * @version 1.0
     * @see
     */
    public static List<String> string2List(String s, String separator) {
        String[] arr = s.split(separator);
        //如果单纯的返回Arrays.asList(arr)的话，则返回的list不能进行remove、add等操作，
        //因为Arrays.asList(arr)返回的是Arrays的内部类，remove、add方法未重写，会抛出UnsupportedOperationException异常
        return new ArrayList(Arrays.asList(arr));
    }


    /**
     * 截取list集合，返回list集合
     *
     * @param list  (需要截取的集合)
     * @param len (每次截取的数量)
     * @return
     */
    public static <T> List<List<T>> subList(List<T> list, Integer len) {
        if (list == null || list.size() == 0 || len < 1) {
            return null;
        }
        List<List<T>> result = new ArrayList<>();
        int size = list.size();
        int count = (size + len - 1) / len;
        for (int i = 0; i < count; i++) {
            List<T> subList = list.subList(i * len, ((i + 1) * len > size ? size : len * (i + 1)));
            result.add(subList);
        }
        return result;
    }

    /**
     * 获取传入数据组 笛卡尔积凭借成的 字符串集合
     *
     * @param strs1
     * @param strs2
     * @param strs3
     * @return
     */
    public static List<String> getArrayCrossJoinList(String[] strs1, String[] strs2, String[] strs3) {
        List<String> resultList = new ArrayList<>();
        if (strs1 == null || strs1.length < 1) {
            return resultList;
        }
        for (int i = 0; i < strs1.length; i++) {
            if (strs2 == null || strs2.length < 1) {
                resultList.add(strs1[i]);
            } else {
                if (strs3 == null || strs3.length < 1) {
                    for (int j = 0; j < strs2.length; j++) {
                        resultList.add(strs1[i] + strs2[j]);
                    }
                } else {
                    for (int j = 0; j < strs2.length; j++) {
                        for (int k = 0; k < strs3.length; k++) {
                            resultList.add(strs1[i] + strs2[j] + strs3[k]);
                        }
                    }
                }
            }
        }
        return resultList;
    }

    /**
     * 提取集合Map里面的key的值
     * 并存入list返回
     *
     * @param mapList
     * @param key
     * @return
     */
    public static List<String> listMap2ListString(List<Map> mapList, String key) {
        Set<String> stringSet = new HashSet();
        mapList.forEach(map -> {
            if (!ValidateUtil.isEmpty(map.get(key))) {
                stringSet.add(map.get(key).toString());
            }
        });
        List<String> strings = new ArrayList();
        strings.addAll(stringSet);
        return strings;
    }

    public static List<Integer> listMap2ListInteger(List<Map> mapList, String key) {
        Set<Integer> integerSet = new HashSet();
        mapList.forEach(map -> {
            if (!ValidateUtil.isEmpty(map.get(key))) {
                integerSet.add(Integer.valueOf(map.get(key).toString()));
            }
        });
        List<Integer> Integers = new ArrayList();
        Integers.addAll(integerSet);
        return Integers;
    }

    /**
     * 提取集合Map里面的key的值
     * 并存入list返回
     *
     * @param mapList
     * @param key
     * @return
     */
    public static List<String> listMyMap2ListString(List<MyMap> mapList, String key) {
        Set<String> stringSet = new HashSet();
        mapList.forEach(map -> {
            if (!ValidateUtil.isEmpty(map.get(key))) {
                stringSet.add(map.get(key).toString());
            }
        });
        List<String> strings = new ArrayList();
        strings.addAll(stringSet);
        return strings;
    }

    /**
     * 提取list里面两个指标
     * 一个作为key,一个作为value
     *
     * @param mapList
     * @param key
     * @return
     */
    public static Map<String, Object> list2Map(List<Map> mapList, String key, String value) {
        Map<String, Object> outMap = new HashMap();
        mapList.forEach(map -> {
            outMap.put(map.get(key).toString(), map.get(value));
        });
        return outMap;
    }

    /**
     * 提取list里面两个指标
     * 一个作为key,一个作为value
     *
     * @param mapList
     * @param key
     * @return
     */
    public static Map<String, Object> listMyMap2Map(List<MyMap> mapList, String key, String value) {
        Map<String, Object> outMap = new HashMap();
        mapList.forEach(map -> {
            outMap.put(map.get(key).toString(), map.get(value));
        });
        return outMap;
    }

    /**
     * 提取集合Map里面的数据
     * 加入list返回
     *
     * @param myMap
     * @return
     */
    public static List<Map> map2List(MyMap myMap) {
        List<Map> list = new ArrayList<>();
        if (ValidateUtil.isEmpty(myMap.get("aae736"))) {
            myMap.put("aae736", myMap.get("aae011"));
        }
        myMap.put("aae739", DateUtil.getCurrentTime("yyyyMMdd"));
        list.add(myMap);
        return list;
    }

    /**
     * 将 List<JavaBean>对象转化为List<Map>
     *
     * @return Object对象
     * @author loulan
     */
    public static List<Map> convertListEntity2ListMap(List<?> beanList) {
        List<Map> mapList = new ArrayList();
        beanList.forEach(object -> {
            Map map = MyMap.convertToMap(object);
            mapList.add(map);
        });
        return mapList;
    }

    /**
     * 将 List<JavaBean>对象转化为List<Map>
     *
     * @return Object对象
     * @author loulan
     */
    public static <T> List<T> convertListMap2ListEntity(List<Map> maps, Class<T> tclass) {
        List<T> list = new ArrayList<>();
        if (ValidateUtil.isEmpty(maps)) {
            return null;
        }
        maps.forEach(map -> {
            T object = MyMap.convertToDomain(new MyMap(map), tclass);
            list.add(object);
        });
        return list;
    }

    public static List<String> listIntege2ListString(List<Integer> tmp) {
        List<String> result = new ArrayList();
        if (ValidateUtil.isNotEmpty(tmp)) {
            tmp.forEach(x -> {
                result.add(x.toString());
            });
        }
        return result;
    }

    /**
     * 按照指定长度将list<String>拆分成List<List<String>>
     *
     * @param list
     * @param len
     * @return
     */
    public static List<List<String>> splitListString(List<String> list, int len) {
        if (list == null || list.size() == 0 || len < 1) {
            return null;
        }
        List<List<String>> result = new ArrayList<>();
        int size = list.size();
        int count = (size + len - 1) / len;
        for (int i = 0; i < count; i++) {
            List<String> subList = list.subList(i * len, ((i + 1) * len > size ? size : len * (i + 1)));
            result.add(subList);
        }
        return result;
    }

    public static List<MyMap> list2MyMapLowerList(List mapList) {
        List<MyMap> list = new ArrayList();
        MyMap k;
        Map m;
        Object o;
        for (int i = 0; i < mapList.size(); i++) {
            try {
                m = (Map) mapList.get(i);
            } catch (Exception e) {
                o = (Object) mapList.get(i);
                m = MapUtil.toMap(o);
            }

            k = new MyMap(m).lowerCaseKeyMap();
            list.add(k);
        }
        return list;
    }

    //暂时加上同步完后删掉
    /**
     * 按照指定长度将list<Map>拆分成List<List<Map>>
     *
     * @param list
     * @param len
     * @return
     */
    public static List<List<Map>> splitListMap(List<Map> list, int len) {
        if (list == null || list.size() == 0 || len < 1) {
            return null;
        }
        List<List<Map>> result = new ArrayList<>();
        int size = list.size();
        int count = (size + len - 1) / len;
        for (int i = 0; i < count; i++) {
            List<Map> subList = list.subList(i * len, ((i + 1) * len > size ? size : len * (i + 1)));
            result.add(subList);
        }
        return result;
    }

    /**
     * 按照指定长度将list<Object>拆分成List<List<Object>>
     *
     * @param list
     * @param len
     * @return
     */
    public static List<List<Object>> splitList(List<Object> list, int len) {
        if (list == null || list.size() == 0 || len < 1) {
            return null;
        }
        List<List<Object>> result = new ArrayList<>();
        int size = list.size();
        int count = (size + len - 1) / len;
        for (int i = 0; i < count; i++) {
            List<Object> subList = list.subList(i * len, ((i + 1) * len > size ? size : len * (i + 1)));
            result.add(subList);
        }
        return result;
    }
    /**
     * 对待遇项目进行合并
     * @param treatments 需要合并的list
     * @param startFiled 记录中的开始时间
     * @param endFiled 结束时间
     * */
    public static List<Map> mergeTreatment(List<? extends Map> treatments,String startFiled,String endFiled){
        if (treatments == null || treatments.size() <= 1){
            if (treatments == null || treatments.size() == 0){
                return new ArrayList<>();
            }else {
                ArrayList<Map> tmpList = new ArrayList<>();
                tmpList.add(new HashMap(treatments.get(0)));
                return tmpList;
            }
        }
        Map<String, ? extends List<? extends Map>> aaa345_group = treatments.stream().collect(Collectors.groupingBy(e -> e.get("aaa345").toString()));
        ArrayList<Map> result = new ArrayList<>();
        for (Map.Entry<String, ? extends List<? extends Map>> entry : aaa345_group.entrySet()) {
            result.addAll(mergeTreatment1(entry.getValue(),startFiled,endFiled));
        }
        return result;
    }
    public static List<Map> mergeTreatment0(List<? extends Map> treatments,String startFiled,String endFiled){
        if (treatments == null || treatments.size() <= 1){
            if (treatments == null || treatments.size() == 0){
                return new ArrayList<>();
            }else {
                ArrayList<Map> tmpList = new ArrayList<>();
                tmpList.add(new HashMap(treatments.get(0)));
                return tmpList;
            }
        }
        //对开始期号和结束期号排序
        List<String> nodeSort = new ArrayList<>();
        HashSet<String> nodes = new HashSet<>();
        List<Map> arrayList = new ArrayList<>();
        for (Map treatment : treatments) {
            NPETool.isEmptyThrowException(treatment.get(startFiled),"开始标志");
            NPETool.isEmptyThrowException(treatment.get(endFiled),"结束标志");
            String start = treatment.get(startFiled).toString();
            String end = treatment.get(endFiled).toString();
            nodes.add(start);
            nodes.add(end);
        }
        nodes.forEach(e->nodeSort.add(e));
        nodeSort.sort(comparing(e->e));
        Map treatmentBase = new HashMap(treatments.get(0));
        treatmentBase.remove(startFiled);
        treatmentBase.remove(endFiled);
        int curIndex = 1;
        String aae041 = nodeSort.get(0);

        Map<String, ? extends List<? extends Map>> collect_start = treatments.stream().collect(Collectors.groupingBy(e -> e.get(startFiled).toString()));
        Map<String, ? extends List<? extends Map>> collect_end = treatments.stream().collect(Collectors.groupingBy(e -> e.get(endFiled).toString()));
        // 默认最初标准
        BigDecimal curStandard = collect_start.get(nodeSort.get(0)).stream().map(e->new BigDecimal(Optional.ofNullable(e.get("aae019")).orElse("0").toString()))
                .reduce(BigDecimal.ZERO,BigDecimal::add);
//        BigDecimal curStandard = BigDecimal.ZERO;
        Integer aae042 = null;
        // 只有一个时间
        if (nodeSort.size() == 1){
            HashMap hashMap = new HashMap<>(treatmentBase);
            hashMap.put(startFiled,aae041);
            hashMap.put(endFiled,aae041);
            hashMap.put("aae019",curStandard.intValue());
            arrayList.add(hashMap);
            return arrayList;
        }
        for (; curIndex < nodeSort.size(); curIndex++) {
            //1
            String currNode = nodeSort.get(curIndex);
            aae041 = Optional.ofNullable(aae041).orElse(nodeSort.get(curIndex));
            List<? extends Map> endList = collect_end.get(nodeSort.get(curIndex));
            List<? extends Map> startList = collect_start.get(nodeSort.get(curIndex));
            startList = startList== null? new ArrayList<>():startList;
            endList = endList== null? new ArrayList<>():endList;

            if (startList.size() > 0){
                HashMap hashMap = new HashMap<>(treatmentBase);
                hashMap.put(startFiled,aae041);
                hashMap.put(endFiled,new Ym(currNode).getLastYm().intValue());
                hashMap.put("aae019",curStandard.toString());
                arrayList.add(hashMap);
                aae041 = currNode;
                for (Map map : startList) {
                    curStandard = curStandard.add(new BigDecimal(Optional.ofNullable(map.get("aae019")).orElse("0").toString()));
                }
            }
            HashMap<Object, Object> tmp = new HashMap<>(treatmentBase);
            tmp.put(startFiled,aae041);
            if (endList.size() > 0){
                for (Map map : endList) {
                    curStandard = curStandard.subtract(new BigDecimal(Optional.ofNullable(map.get("aae019")).orElse("0").toString()));
                }
                aae042 = Integer.valueOf(currNode);
                tmp.put(endFiled,aae042);
                tmp.put("aae019",curStandard.intValue());
                arrayList.add(tmp);
                aae041 = new Ym(currNode).getNextYm().toString();
            }
        }
        //排序
        arrayList = arrayList.stream().sorted(comparing(m -> m.get("aae041").toString())).collect(Collectors.toList());
        //合并
//        if(arrayList.size() <= 1){
//            return arrayList;
//        }
//        for (int i = 0; i < arrayList.size()-1; i++) {
//            // 金额相等
//            if (Objects.equals(arrayList.get(i).get("aae019").toString(),arrayList.get(i+1).get("aae019").toString())){
//                // 连续
//                if (Objects.equals(new Ym(arrayList.get(i).get("aae042").toString()).getNextYm().toString(),new Ym(arrayList.get(i+1).get("aae041").toString()).getNextYm().toString())){
//                    arrayList.get(i+1).put("aae041",arrayList.get(i).get("aae041"));
//                    arrayList.set(i,null);
//                }
//            }
//        }

        return arrayList;
    }
    public static int getNextMonth(int month){
        if (month < 100000 || month > 999912){
            throw new IllegalArgumentException("月份格式错误");
        }
        int year = month/100;
        int mon = month%100 + 1;
        if (mon > 12){
            return (year + 1 )*100 + 1;
        }else {
            return year*100 + mon;
        }
    }
    /**
     * 相同待遇项目*/
    public static List<Map> mergeTreatment1(List<? extends Map> treatments,String startFiled,String endFiled){
        HashMap<Object, Object> tmplate = new HashMap<>(treatments.get(0));
        tmplate.remove("aae019");
        tmplate.remove("aae041");
        tmplate.remove("aae042");
        HashMap<String, BigDecimal> aae019Objects = new HashMap<>();
        ArrayList<Map> result = new ArrayList<>();
        Integer start = 999912;
        Integer end = 100000;
        String aaa345 = tmplate.get("aaa345").toString();
        for (Map treatment : treatments) {
            Integer aae041 = Integer.parseInt(treatment.get("aae041").toString());
            Integer aae042 = Integer.parseInt(treatment.get("aae042").toString());
            start = Math.min(start,aae041);
            end = Math.max(end,aae042);
            BigDecimal aae019 = new BigDecimal(Optional.ofNullable(treatment.get("aae019")).orElse("0").toString());
            for (int i = aae041; i <= aae042; i = getNextMonth(i)) {
                String key = aaa345 + "," + i;
                BigDecimal bigDecimal = aae019Objects.get(key);
                if (bigDecimal == null){
                    aae019Objects.put(key,aae019);
                }else {
                    aae019Objects.put(key,bigDecimal.add(aae019));
                }
            }
        }
        Integer aae041 = start;
        for (int i = start; i <= end; i=getNextMonth(i)) {
            BigDecimal aae019 = aae019Objects.get(aaa345 + "," + i);
            if (aae019 == null){
                aae041 = null;
                continue;
            }
            if (aae041 == null){
                aae041 = i;
            }
            if (Objects.equals(aae019,aae019Objects.get(aaa345 + "," + getNextMonth(i)))){

                continue;
                // 和下个月相等
            }else {
                HashMap<Object, Object> tmp = new HashMap<>(tmplate);
                tmp.put("aae041",aae041.toString());
                tmp.put("aae042",String.valueOf(i));
                tmp.put("aae019",aae019);
                result.add(tmp);
                aae041 = null;
            }
        }
        return result;
    }


    }
